/*
 * File:   synchrone.cpp
 * Author: cyril
 *
 * Created on 10 décembre 2012, 09:33
 */
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

#define MAXSIZE 10

typedef struct {
    char
    data [MAXSIZE];
    int
    datasize;
    MPI_Request req;
} Buffer;

void produce(int rank, char* data, int* datasize) {
    strcpy(data, "Bonjour !");
    *datasize = 10;
    printf("Un producteur (processus n° %d) a produit le message [%s,%d]\n",
            rank, data, *datasize);
}

void consume(int rank, char* data, int datasize) {
    printf("Un consommateur (processus n° %d) a consommé le message [%s,%d]\n",
            rank, data, datasize);
}

/*********
/* DEBUT DU PROGRAMME IDENTIQUE AU DEUX VERSIONS DU PRODUCTEUR-CONSOMMATEUR
 *******/
int main(int argc, char** argv) {
    int rank, size, i;
    Buffer*
            b;
    MPI_Status status;
    MPI_Init(&argc, &argv);
    /* Initialisation de MPI */
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    if (rank != size - 1) {
        /* PRODUCTEUR */
        b = (Buffer *) malloc(sizeof (Buffer));
        while (1) {
            produce(rank, b->data, &b->datasize);
            MPI_Send(b->data, b->datasize, MPI_CHAR, size - 1, 99, MPI_COMM_WORLD);
        }
    }
        /************** FIN DU PROGRAMME VERSION 1 *********************/
    else {
        /* CONSOMMATEUR */
        b = (Buffer *) malloc(sizeof (Buffer)*(size - 1));
        for (i = 0; i < size - 1; i++)
            MPI_Irecv(b[i].data, MAXSIZE, MPI_CHAR, i, 99, MPI_COMM_WORLD, &(b [i].req));
        for (i = 0;; i = (i + 1) % (size - 1)) {
            MPI_Wait(&(b[i].req), &status);
            MPI_Get_count(&status, MPI_CHAR, &(b[i].datasize));
            consume(rank, b[i].data, b[i].datasize);
            MPI_Irecv(b[i].data, MAXSIZE, MPI_CHAR, i, 99, MPI_COMM_WORLD, &(b [i].req));
        }
    }
    MPI_Finalize();
}



